//******************************************************************************************************
// Copyright 2008 Amazon Technologies, Inc.  
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in 
// compliance with the License. 
//
// You may obtain a copy of the License at:http://aws.amazon.com/apache2.0  This file is distributed on 
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
//
// See the License for the specific language governing permissions and limitations under the License. 
//******************************************************************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SQS_Sample_Object;

namespace SQS_Sample_Worker
{
    public partial class StockQuoteWorker : Form
    {
        SQS.Worker  _worker = new SQS.Worker();
        DateTime    _startTime = DateTime.Now;
        long        _maxQueueDepth = 0; 

        public StockQuoteWorker()
        {
            InitializeComponent();
     
            //
            // Initialize our worker object - it runs independently of the requestor object
            //
            _worker.AwsID = "Please Fill in";
            _worker.AWSSecretKey = "Please Fill in";
            _worker.Queue                = "StockQueue";
            _worker.requestEvent        += new SQS.Worker.ProcessEvent(worker_requestEvent);
            _worker.MeasureNetLatency  = true;
            
            Start.Enabled   = true;
            Stop.Enabled    = false;
        }

        private void Start_Click(object sender, EventArgs e)
        {
            _worker.Threads          = Convert.ToInt32(nThreads.Value);
            _worker.ReceiveDelay     = Convert.ToInt32(nPollRate.Value);
            
            switch (pollingMode.SelectedIndex)
            {
                default:
                case 0:     // Adaptive
                    _worker.PollingMode = SQS.SQSManager.pollMode.Adaptive;
                    break;
                case 1:     // Manual
                    _worker.PollingMode = SQS.SQSManager.pollMode.Manual;
                    break;
            }

            _worker.Start();
            pollingMode.Enabled     = false;
            Start.Enabled           = false;
            Stop.Enabled            = true;
            nThreads.Enabled        = false;
            nPollRate.Enabled       = false;
            _startTime              = DateTime.Now;
        }

        private void Stop_Click(object sender, EventArgs e)
        {
            _worker.Stop();
            Start.Enabled           = true;
            Stop.Enabled            = false;
            nThreads.Enabled        = true;
            nPollRate.Enabled       = true;
            pollingMode.Enabled     = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int    si = 0;
            string st = Properties.Settings.Default.PollingMode;
            
            for (int i = 0; i < pollingMode.Items.Count; i++)
            {
                if (st == (string)pollingMode.Items[i]) 
                {
                    si = i;
                    break;
                }
            }
            
            pollingMode.SelectedIndex = si;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            string st = (string)pollingMode.Items[pollingMode.SelectedIndex];
            _worker.Stop();
            
            Properties.Settings.Default.PollingMode = st;
            Properties.Settings.Default.Save();
        }

        private static bool worker_requestEvent(SQS.Worker worker, SQS.SQSMessage message)
        {
            string quote;
            
            //
            // Retrieve the stock quote from the web
            //
            quote  = StockQuote.Retrieve(message._payload);
        
            //
            // Send the response back
            //
            worker.PutResponse(message, quote);

            return true;
        }

        private void displayTime_Tick(object sender, EventArgs e)
        {
            TimeSpan    ts = DateTime.Now.Subtract(_startTime);
            
            double cost;
            double cost_per_hr;

            tbProcessed.Text        = String.Format("{0:N0}", _worker.RequestsProcessed);
            tbProcessErrors.Text    = String.Format("{0:N0}", _worker.ProcessingErrors);
            tbsSQSErrors.Text       = String.Format("{0:N0}", _worker.ReceiveTimeOuts + _worker.ReceiveErrors);
            tbAvgProcessTime.Text   = String.Format("{0:N2}", _worker.AverageProcessMS);

            if (_worker.MessageCount == -1)
            {
                tbQueueDepth.Text = "n/a";
            }
            else
            {
                tbQueueDepth.Text = String.Format("{0:N0}", _worker.MessageCount);
            }

            tbMaxQueueDepth.Text    = String.Format("{0:N0}", _maxQueueDepth);

            countRecv.Text          = String.Format("{0:N0}", _worker.Receives);
            countDel.Text           = String.Format("{0:N0}", _worker.Deletes);
            countMsgCount.Text      = String.Format("{0:N0}", _worker.GetMessageCount);

            tbWorkerThreads.Text    = String.Format("{0:N0}", _worker.ActiveThreads);

            cost            = (double)(_worker.Receives + _worker.Deletes + _worker.GetMessageCount) / 1000000.0;
            cost_per_hr     = cost / ts.TotalHours;

            if (Stop.Enabled)
            {
                tbTimeRunning.Text      = String.Format("{0:0} days, {1:00}:{2:00}:{3:00}", 
                                                        ts.Days, ts.Hours, ts.Minutes, ts.Seconds);
                tbApproxCost.Text       = String.Format("{0:c}", cost);
                tbApproxCostperMin.Text = String.Format("{0:c}", cost_per_hr);
            }
            else
            {
                tbTimeRunning.Text      = "n/a";
                tbApproxCost.Text       = "n/a";
                tbApproxCostperMin.Text = "n/a";
            }

            if (_worker.Receives > 0)
            {
                double effeciency = (double)_worker.RequestsProcessed / (double)_worker.Receives;
                tbWorkerEfficiency.Text = String.Format("{0:N3}", effeciency);
            }
            else
            {
                tbWorkerEfficiency.Text = "n/a";
            }

            if (_worker.AverageLatency != -1)
            {
                tbAvgLatency.Text = String.Format("{0:N2}", _worker.AverageLatency);
            }
            else
            {
                tbAvgLatency.Text = "n/a";
            }

            if (_worker.NetworkLatency != -1)
            {
                double sqs_latency;
                tbNetworkLatency.Text = String.Format("{0:N2}", _worker.NetworkLatency);
                sqs_latency = _worker.AverageLatency - (double)_worker.NetworkLatency;
               
                if (sqs_latency > 0.0)
                {
                    tbSQSLatency.Text = String.Format("{0:N2}", sqs_latency);
                }
                else
                {
                    tbSQSLatency.Text = "n/a";
                }
            }
            else
            {
                tbNetworkLatency.Text = "n/a";
                tbSQSLatency.Text     = "n/a";
            }

            if (_worker.MessageCount > _maxQueueDepth) _maxQueueDepth = _worker.MessageCount;
        }

        private void pollingMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            string st = (string)pollingMode.Items[pollingMode.SelectedIndex];
        }
    }
}